
    /*       简易http服务器服务端        */
    /*       网络层协议：http协议        */
    /*       传输层协议：tcp协议         */
    /*      读取请求，返回正文内容       */
    /*         依赖文件：.html           */
    /*            2018-10-15             */



#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define LENTH ((1024)*(10))

char str[LENTH] = {0};

char* ReadBody()
{
    int fd = open("/home/liu/Internet/http/body.html", O_RDWR, 0664);
    if(fd < 0)
    {
        perror("open");
        return NULL;
    }
    int ret = read(fd, str, 1024*10);
    if(ret < 0)
    {
        perror("error");
        return;
    }
    close(fd);
    return str;
}

void serverIO(int sock)
{
    char recv_buff[LENTH] = {0};
    if(read(sock, recv_buff, LENTH - 1) <= 0)
    {
        perror("read error");
        close(sock);
        return;
    }
    else
        printf("ASK [%s]\n", recv_buff);
    const char* first_line = "HTTP/1.1 200 Ok\r\n";
    const char* blank = "\r\n";
    const char* body = ReadBody();
    char head[LENTH] = {0};
    sprintf(head, "Content-Type: text/html\r\n"
            ,"Accept-Language: zh=CN\r\n"
            ,"Content-Length: %lu\r\n", strlen(body));
    write(sock, first_line, strlen(first_line));
    write(sock, head, strlen(head));
    write(sock, blank, strlen(blank));
    write(sock, body, strlen(body));
    memset(str, 0, 1024*10);
    close(sock);
    return;
}

void* server(void* argc)
{
    int sock = (int)argc;
    serverIO(sock);
    return NULL;
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        printf("Please Input With IP and Port!\n");
        return 0;
    }
    else
        daemon(0, 0);

    int listen_sock;
    int new_sock;
    struct sockaddr_in local;

    listen_sock = socket(AF_INET, SOCK_STREAM, 0);
    if(listen_sock < 0)
    {
        perror("socket error");
        return 0;
    }

    local.sin_family = AF_INET;
    local.sin_port = htons(atoi(argv[2]));
    local.sin_addr.s_addr = inet_addr(argv[1]);
 
    if(bind(listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0)
    {
        perror("bind");
        return 0;
    }

    if(listen(listen_sock, 5) < 0)
    {
        perror("listen error");
        return 0;
    }
    while(1)
    {
        struct sockaddr_in client;
        socklen_t len = 0;
        int sock = accept(listen_sock, (struct sockaddr*)&client, &len);
        pthread_t pid;
        if(sock < 0)
            continue;
        pthread_create(&pid, NULL, server, (void*)sock);
        pthread_detach(pid);    
    }
    
}

